﻿using System;
using System.IO;
using System.Web;
using System.Drawing;

namespace XCommon.utils
{
    public class Waters
    {
        private string mResource;               // 原图实际硬盘地址
        private string mVirtual;                // 原图虚拟路径地址
        private string mFileName;               // 图像保存后的名字(不带后缀名)
        private bool mIsCardRect = true;       // 是否从中间截取

        public string Resource
        {
            get { return mResource; }
            set { mResource = value; }
        }

        public string Virtual
        {
            get { return mVirtual; }
            set { mVirtual = value; }
        }

        public string FileName
        {
            get
            {
                if (string.IsNullOrEmpty(mFileName))
                {
                    mFileName = Guid.NewGuid().ToString("N");
                }
                return mFileName;
            }
        }

        private Waters()
        {
        }

        public static Waters SaveAs(HttpPostedFile file)
        {
            Waters retWaters = new Waters();
            string folderPath = Path.Combine(WaterConfig.It.R, WaterConfig.It.TodayUpPath);
            string vfolderPath = Path.Combine(WaterConfig.It.VR, WaterConfig.It.TodayUpPath);
            if (!Directory.Exists(folderPath))
            {
                try
                {
                    Directory.CreateDirectory(folderPath);
                }
                catch
                {
                    throw new Exception("无法创建图片存储路径");
                }
            }

            string extendName = Path.GetExtension(file.FileName).ToLower();
            if (extendName != ".png"
                    && extendName != ".gif"
                    && extendName != ".jpg"
                    && extendName != ".jpeg"
                    && extendName != ".bmp")
            {
                throw new Exception("头像的文件扩展名不能是" + extendName);
            }

            string imageName = retWaters.FileName + extendName;
            string imageFileName = Path.Combine(folderPath, imageName);
            try
            {
                file.SaveAs(imageFileName);
                retWaters.Resource = imageFileName;
                retWaters.Virtual = Path.Combine(vfolderPath, imageName);
                return retWaters;
            }
            catch
            {
                throw;
            }
        }

        public string SavaAsX1()
        {
            string imageFolder = Path.Combine(WaterConfig.It.X1, WaterConfig.It.TodayUpPath);
            string vimageFolder = Path.Combine(WaterConfig.It.VX1, WaterConfig.It.TodayUpPath);
            string imageFileName = Path.Combine(imageFolder, FileName + "." + WaterConfig.ImageFormat.ToString());
            string vimageFileName = Path.Combine(vimageFolder, FileName + "." + WaterConfig.ImageFormat.ToString());
            try
            {
                MakeThumbnail(WaterConfig.It.X1Size, imageFolder);
                return vimageFileName;
            }
            catch
            {
                throw;
            }
        }

        private void MakeThumbnail(Size newFileSize, string imagePathWithOutName)
        {
            Image image = null;
            Bitmap newBitmap = new Bitmap(newFileSize.Width, newFileSize.Height);
            Graphics g = Graphics.FromImage(newBitmap);                                             // 新建一个画板    
            try
            {
                if (!Directory.Exists(imagePathWithOutName))
                {
                    try
                    {
                        Directory.CreateDirectory(imagePathWithOutName);
                    }
                    catch
                    {
                        throw new Exception("无法创建图片存储路径");
                    }
                }
                image = Image.FromFile(Resource);
                string savePathAndName = Path.Combine(imagePathWithOutName, FileName + "." + WaterConfig.ImageFormat.ToString());
                Size buildSize = DesignNewImageSize(image.Size, newFileSize);
                if (buildSize == image.Size)
                {
                    image.Save(savePathAndName);
                }
                else
                {

                    int moveWidth = 0;
                    int moveHeight = 0;
                    if (mIsCardRect)
                    {
                        moveWidth = (image.Width - buildSize.Width) / 2;
                        moveHeight = (image.Height - buildSize.Height) / 2;
                    }

                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;              // 设置高质量插值法            
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;               // 设置高质量,低速度呈现平滑程度
                    g.Clear(System.Drawing.Color.Transparent);                                          // 清空画布并以透明背景色填充

                    g.DrawImage(image,
                        new System.Drawing.Rectangle(0, 0, newFileSize.Width, newFileSize.Height),
                        new System.Drawing.Rectangle(moveWidth, moveHeight, buildSize.Width, buildSize.Height),
                        System.Drawing.GraphicsUnit.Pixel);

                    newBitmap.Save(savePathAndName, WaterConfig.ImageFormat);
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                if (image != null) image.Dispose();
                if (g != null) { g.Dispose(); }
                if (newBitmap != null) { newBitmap.Dispose(); }
            }
        }

        private Size DesignNewImageSize(Size imageSize, Size newSize)
        {
            Size retSize;
            if (imageSize.Height > newSize.Height)
            {
                if (imageSize.Width > newSize.Width)
                {
                    // 都大
                    double dW = ((double)imageSize.Width) / newSize.Width;
                    double dH = ((double)imageSize.Height) / newSize.Height;
                    double move = dW > dH ? dH : dW;
                    retSize = new Size((int)(newSize.Width * move), (int)(newSize.Height * move));
                }
                else
                {
                    // 高大，宽小
                    retSize = new Size(imageSize.Width, newSize.Height);
                }
            }
            else
            {
                if (imageSize.Width > newSize.Width)
                {
                    // 高小,宽大
                    retSize = new Size(newSize.Width, imageSize.Height);
                }
                else
                {
                    // 都小
                    retSize = new Size(imageSize.Width, imageSize.Height);
                }
            }

            return retSize;
        }

    }

    public class WaterConfig : Code.DO<WaterConfig>
    {
        private const string mDefaultUpPath = "up";
        private const string mX3 = "x3";
        private const string mX2 = "x2";
        private const string mX1 = "x1";
        private const string mR = "r";
        public static System.Drawing.Imaging.ImageFormat ImageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;

        // 硬盘路径
        private string mUpPath;
        private string mX3Path;
        private string mX2Path;
        private string mX1Path;
        public string mRPath;

        // 虚拟路径
        private string mVUpPath;
        private string mVX3Path;
        private string mVX2Path;
        private string mVX1Path;
        private string mVRPath;

        private Size mX1Size = new Size(480, 800);
        private Size mX2Size = new Size(480, 880);
        private Size mX3Size = new Size(480, 880);

        public Size X1Size { get { return mX1Size; } }
        public Size X2Size { get { return mX2Size; } }
        public Size X3Size { get { return mX3Size; } }

        public string UpPath
        {
            get
            {
                if (string.IsNullOrEmpty(mUpPath))
                {
                    mUpPath = Path.Combine(HttpRuntime.AppDomainAppPath, mDefaultUpPath);
                }
                return mUpPath;
            }
        }

        public string VUpPath
        {
            get
            {
                if (string.IsNullOrEmpty(mVUpPath))
                {
                    mVUpPath = Path.Combine("~/", mDefaultUpPath);
                }
                return mVUpPath;
            }
        }

        public string R
        {
            get
            {
                if (string.IsNullOrEmpty(mRPath))
                {
                    mRPath = Path.Combine(UpPath, mR);
                }
                return mRPath;
            }
        }

        public string VR
        {
            get
            {
                if (string.IsNullOrEmpty(mVRPath))
                {
                    mVRPath = Path.Combine(VUpPath, mR);
                }
                return mVRPath;
            }
        }

        public string X1
        {
            get
            {
                if (string.IsNullOrEmpty(mX1Path))
                {
                    mX1Path = Path.Combine(UpPath, mX1);
                }
                return mX1Path;
            }
        }

        public string VX1
        {
            get
            {
                if (string.IsNullOrEmpty(mVX1Path))
                {
                    mVX1Path = Path.Combine(VUpPath, mX1);
                }
                return mVX1Path;
            }
        }

        public string X2
        {
            get
            {
                if (string.IsNullOrEmpty(mX2Path))
                {
                    mX2Path = Path.Combine(UpPath, mX2);
                }
                return mX2Path;
            }
        }

        public string VX2
        {
            get
            {
                if (string.IsNullOrEmpty(mVX2Path))
                {
                    mVX2Path = Path.Combine(VUpPath, mX2);
                }
                return mVX2Path;
            }
        }

        public string X3
        {
            get
            {
                if (string.IsNullOrEmpty(mX3Path))
                {
                    mX3Path = Path.Combine(UpPath, mX3);
                }
                return mX3Path;
            }
        }

        public string VX3
        {
            get
            {
                if (string.IsNullOrEmpty(mVX3Path))
                {
                    mVX3Path = Path.Combine(VUpPath, mX3);
                }
                return mVX3Path;
            }
        }

        public string TodayUpPath
        {
            get
            {
                DateTime now = DateTime.Now;
                return string.Format("{0}/{1}/{2}", now.Year, now.Month, now.Day);
            }
        }

    }
}
